package robot;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

/**
 * Servlet implementation class WeChat
 */
@WebServlet({ "/WeChat", "/wechat" })
public class WeChatServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    private Logger log = Logger.getLogger(this.getClass());
    public static final class TYPES {
    	String Subscribe = "subscribe";
    }
    
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WeChatServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		log.info("in do get");
		
		log.debug("set response header: Access-Control-Allow-Origin");
		response.setContentType("text/html;charset=utf-8");
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Access-Control-Allow-Origin", "*");//cross domain request/CORS
		
		log.info("request.getContextPath(): " + request.getContextPath());
		String action = request.getParameter("action");	
		log.debug("action is: " + action);	
		
		String echoStr = request.getParameter("echostr");
		if (echoStr!=null&&!echoStr.isEmpty()) {
			response.getWriter().write(echoStr);
		} else {
			log.info("request does not contains echostr");
		}
	}

	/**
	 * TODO create another method to deal text, so that easy to test
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		log.info("on do post");	
		
		log.debug("set character encoding to utf-8");
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		
		log.info("send result XML string to response");
		response.getWriter().append(getXMLResponseFromWeChat(request));
	}

	private CharSequence getXMLResponseFromWeChat(HttpServletRequest request) {
		try {		
			//response.getWriter().append("you are posting:");
			log.info("1. get request data stream");
			String requestStr = getRequestData(request);
			log.debug("request data is: " + requestStr);

			log.info("get uName from XML");
			String uName = getUNameFromRequestXML(requestStr);
			try {
				log.info("2. get message from XML string");
				String message = getMessageFromXMLStr(requestStr);
				String type = getTypeFromXMLStr(requestStr);
	
				log.info("3. get answer");
				AnswerMachine machine = new AnswerMachine();
				//此处应有MAP
				String answer = machine.getAnswer(type, uName, message);
				
				log.info("4. create XML string from answer message");
				String result = createWeChatXMLReply(uName, answer);
				log.debug("XML result is: " + result);
	

				return result;
			} catch (Throwable t) {
				log.error("success on get uName(" + uName + "), error and last steps:");
				log.error(t);
				return createWeChatXMLReply(uName, "哎，兄弟你把胖哥玩坏了");
			}
		} catch (Throwable t) {
			log.error("error", t);
			return "";
		}
	}

	public String createWeChatXMLReply(String uName, String message) {
		String result = "<xml>"
				+ "<ToUserName><![CDATA[" + uName + "]]></ToUserName>"
				+ "<FromUserName><![CDATA[gh_217a7523db88]]></FromUserName>"
				+ "<CreateTime>12345678</CreateTime>"
				+ "<MsgType><![CDATA[text]]></MsgType>"
				+ "<Content><![CDATA[" + message + "]]></Content>"
				+ "</xml>";
		return result;
	}

	  /*读取request数据*/  
    public static String getRequestData(HttpServletRequest request) throws IOException{  
        BufferedReader reader = request.getReader();  
        char[] buf = new char[512];  
        int len = 0;  
        StringBuffer contentBuffer = new StringBuffer();  
        while ((len = reader.read(buf)) != -1) {  
            contentBuffer.append(buf, 0, len);  
        }
        
        String content = contentBuffer.toString();  
        if(content == null){  
            content = "";  
        }  
        return content;  
    }
    
	private String getUNameFromRequestXML(String requestXML) {
		return getDataFromXMLStr(requestXML, "<FromUserName><![CDATA[", "]]></FromUserName>");
	}
    
    protected String getMessageFromXMLStr(String requestXML) {
    	return getDataFromXMLStr(requestXML, "<Content><![CDATA[", "]]></Content>");
    }
    
    public String getTypeFromXMLStr(String requestXML) {
		if(requestXML.contains("<Event><![CDATA[subscribe]]></Event>")) {
			return "subscribe";
		} else {
			return "message";
		}
    }
    
    public String getDataFromXMLStr(String holeXML, String start, String end) {
    	if(holeXML!=null&&!holeXML.isEmpty()&&
    			holeXML.contains(start)&&holeXML.contains(end)) {
    		String result = holeXML.substring(holeXML.indexOf(start) + start.length(), holeXML.indexOf(end));
    		log.debug("getting data, result is: " + result);
    		return result;
    	} else {
    		log.debug("error on getting data, return empty string");
    		return "";
    	}
    }
}
